package cn.ctvonline.android.kaopu.support.net;

import android.text.TextUtils;

import com.squareup.okhttp.FormEncodingBuilder;
import com.squareup.okhttp.OkHttpClient;
import com.squareup.okhttp.Request;
import com.squareup.okhttp.RequestBody;
import com.squareup.okhttp.Response;

import java.io.IOException;
import java.net.Proxy;
import java.util.Map;
import java.util.concurrent.TimeUnit;

/**
 * Created by dujian on 15/12/25.
 */
public class HttpComponent {
    private final static OkHttpClient httpClient = new OkHttpClient();
    private final static ThreadLocal<HttpComponent> threadLocal = new ThreadLocal<>();
    private static Map<String, String> mHeaders;

    private HttpComponent() {
    }

    public enum RequestMethod {
        GET, POST
    }

    public static HttpComponent getInstance() {
        if (null == threadLocal.get()) {
            threadLocal.set(new HttpComponent());
        }
        return threadLocal.get();
    }

    public static void init(Builder builder) {
        httpClient.setProxy(builder.proxy);
        httpClient.setConnectTimeout(builder.coonTimeout, builder.connUnit);
        httpClient.setReadTimeout(builder.readTimeout, builder.readUnit);
        httpClient.setRetryOnConnectionFailure(builder.retryOnConnectionFailure);
        httpClient.setWriteTimeout(builder.writeTimeout, builder.writeUnit);
        mHeaders = builder.headers;
    }

    public String execute(String url, Map<String, String> params, RequestMethod requestMethod) {
        String content = "";
        if (!TextUtils.isEmpty(url)) {
            throw new RuntimeException("http execute url is null");
        }
        Request request = null;
        Request.Builder rBuilder = new Request.Builder();
        if (mHeaders != null && mHeaders.size() > 0) {
            for (Map.Entry<String, String> entry : mHeaders.entrySet()) {
                rBuilder.header(entry.getKey(), entry.getValue());
            }
        }

        if (params != null && params.size() > 0) {
            if (requestMethod == RequestMethod.POST) {
                FormEncodingBuilder formBuilder = new FormEncodingBuilder();
                for (Map.Entry<String, String> entry : params.entrySet()) {
                    formBuilder.add(entry.getKey(), entry.getValue());
                }
                RequestBody body = formBuilder.build();
                rBuilder.post(body);
            } else {
                StringBuilder paramter = new StringBuilder("");
                if (url.indexOf("?") == -1) {
                    paramter.append("?");
                } else {
                    paramter.append("&");
                }
                for (Map.Entry<String, String> entry : params.entrySet()) {
                    paramter.append(entry.getKey() + "=" + entry.getValue() + "&");
                }
                url += paramter.toString();
            }
        }
        request = rBuilder.url(url).build();
        try {
            Response response = httpClient.newCall(request).execute();
            if (response != null && response.isSuccessful()) {
                content = response.body().string();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        return content;
    }

    public static class Builder {
        private Proxy proxy;
        private long coonTimeout = 15 * 1000;
        private TimeUnit connUnit = TimeUnit.SECONDS;
        private long readTimeout = 15 * 1000;
        private TimeUnit readUnit = TimeUnit.SECONDS;
        private long writeTimeout = 15 * 1000;
        private TimeUnit writeUnit = TimeUnit.SECONDS;
        private boolean retryOnConnectionFailure = true;
        private Map<String, String> headers;

        public void setProxy(Proxy proxy) {
            this.proxy = proxy;
        }

        public void setReadTimeout(long timeout, TimeUnit unit) {
            this.readTimeout = timeout;
            this.readUnit = unit;
        }

        public void setConnectTimeout(long timeout, TimeUnit unit) {
            this.coonTimeout = timeout;
            this.connUnit = unit;
        }

        public void setRetryOnConnectionFailure(boolean retryOnConnectionFailure) {
            this.retryOnConnectionFailure = retryOnConnectionFailure;
        }

        public void setWriteTimeout(long writeTimeout, TimeUnit writeUnit) {
            this.writeTimeout = writeTimeout;
            this.writeUnit = writeUnit;
        }

        public void setHeaders(Map<String, String> headers) {
            this.headers = headers;
        }

        public Builder build() {
            return this;
        }
    }
}
